<template>
  <view class="page">
    <view class="section">
      <button :disabled="scanning" @click="startScan">{{ scanning ? '扫描中...' : '开始扫描' }}</button>
      <button @click="stopScan">停止扫描</button>
    </view>

    <view class="section">
      <view v-if="devices.length === 0">未找到设备</view>
      <view v-for="d in devices" :key="d.deviceId" class="device">
        <text>{{ d.name || '未知设备' }} (RSSI: {{ d.RSSI }})</text>
        <button @click="connectDevice(d)">{{ connectedDeviceId === d.deviceId ? '已连接' : '连接' }}</button>
      </view>
    </view>

    <view v-if="connectedDeviceId" class="section">
      <text>已连接设备: {{ connectedDeviceName }}</text>
      <view class="row">
        <button @click="discoverServices">发现服务 & 特征</button>
        <button @click="disconnect">断开连接</button>
      </view>

      <view class="subsection">
        <text>选定特征（notify/write/read）</text>
        <picker :value="selectedCharIndex" @change="onSelectChar">
          <view class="picker">{{ selectedCharName || '请选择特征' }}</view>
          <view class="options" slot="options" v-if="false"></view>
        </picker>

        <view v-for="(c, idx) in characteristics" :key="c.uuid" class="char">
          <text>#{{ idx }} {{ c.uuid }}</text>
          <text>properties: {{ JSON.stringify(c.properties) }}</text>
        </view>

        <view class="row">
          <input v-model="writeText" placeholder="输入写入的字符串 (utf8/hex 支持)" />
          <button @click="writeChar">写入</button>
        </view>

        <view class="row">
          <button @click="readChar">读取</button>
          <button @click="toggleNotify">{{ isNotifying ? '关闭通知' : '开启通知' }}</button>
        </view>

        <view class="log">
          <text>日志：</text>
          <view v-for="(l, i) in logs" :key="i">
            <text>{{ l }}</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import Bluetooth from '@/utils/bluetooth.js' // 请确保路径正确

export default {
  data() {
    return {
      scanning: false,
      devices: [],
      connectedDeviceId: null,
      connectedDeviceName: '',
      services: [],
      characteristics: [],
      selectedCharIndex: -1,
      writeText: '',
      isNotifying: false,
      logs: []
    }
  },
  methods: {
    log(msg) {
      const t = `${new Date().toLocaleTimeString()} - ${msg}`
      this.logs.unshift(t)
      console.log(t)
    },

    async startScan() {
      this.devices = []
      this.scanning = true
      this.log('开始初始化蓝牙适配器...')
      try {
        await Bluetooth.init()
        this.log('蓝牙适配器就绪，开始扫描...')
        Bluetooth.onDeviceFound(this.onDeviceFound)
        await Bluetooth.startDiscovery()
        this.log('已开始发现设备...')
      } catch (err) {
        this.log('启动扫描失败: ' + (err && err.errMsg ? err.errMsg : err))
        this.scanning = false
      }
    },

    stopScan() {
      this.scanning = false
      Bluetooth.stopDiscovery().then(() => {
        this.log('停止发现设备')
      }).catch(err => {
        this.log('停止发现设备出错: ' + JSON.stringify(err))
      })
    },

    onDeviceFound(dev) {
      // dev: { deviceId, name, RSSI, advertisData... }
      const exist = this.devices.find(d => d.deviceId === dev.deviceId)
      if (!exist) {
        this.devices.push(dev)
        // 按RSSI排序（信号强到弱）
        this.devices.sort((a, b) => (b.RSSI || -999) - (a.RSSI || -999))
        this.$apply && this.$apply() // 在小程序原生回调里触发视图更新（必要时）
      }
    },

    async connectDevice(d) {
      if (this.connectedDeviceId) {
        await this.disconnect()
      }
      this.log('尝试连接：' + (d.name || d.deviceId))
      try {
        const res = await Bluetooth.createConnection(d.deviceId)
        this.connectedDeviceId = d.deviceId
        this.connectedDeviceName = d.name || d.deviceId
        this.log('已连接: ' + d.deviceId)
        // 监听断开、特征通知
        Bluetooth.onConnectionStateChange(this.onConnectionStateChange)
        Bluetooth.onBLECharacteristicValueChange(this.onCharacteristicChanged)
        // 自动发现服务/特征
        await this.discoverServices()
      } catch (err) {
        this.log('连接失败: ' + JSON.stringify(err))
      }
    },

    async discoverServices() {
      if (!this.connectedDeviceId) return
      this.log('发现服务...')
      try {
        this.services = await Bluetooth.getServices(this.connectedDeviceId)
        this.log('服务数量: ' + this.services.length)
        // 为第一个服务获取特征（真实项目中需要根据UUID选择）
        const serviceId = this.services[0] && this.services[0].uuid
        if (!serviceId) {
          this.log('未发现服务')
          return
        }
        this.characteristics = await Bluetooth.getCharacteristics(this.connectedDeviceId, serviceId)
        this.log('特征数量: ' + this.characteristics.length)
        this.selectedCharIndex = this.characteristics.length ? 0 : -1
      } catch (err) {
        this.log('发现服务失败: ' + JSON.stringify(err))
      }
    },

    onSelectChar(e) {
      // 未使用原生 picker 的 value，这里演示 placeholder
      this.selectedCharIndex = parseInt(e.detail.value) || 0
    },

    async writeChar() {
      if (this.selectedCharIndex < 0) {
        this.log('请先选择特征')
        return
      }
      const ch = this.characteristics[this.selectedCharIndex]
      if (!ch.properties.write && !ch.properties.writeWithoutResponse) {
        this.log('该特征不可写')
        return
      }
      // 支持纯十六进制(hex: 0x...) 或 utf8 字符串
      let buffer
      const txt = this.writeText.trim()
      if (txt.startsWith('0x')) {
        buffer = Bluetooth.hexToArrayBuffer(txt.replace(/^0x/, ''))
      } else {
        buffer = Bluetooth.stringToArrayBuffer(txt)
      }
      try {
        await Bluetooth.writeCharacteristic(this.connectedDeviceId, ch.serviceId || ch.serviceUuid || ch.service, ch.uuid || ch.characteristicUuid || ch.uuid, buffer)
        this.log('写入成功')
      } catch (err) {
        this.log('写入失败: ' + JSON.stringify(err))
      }
    },

    async readChar() {
      if (this.selectedCharIndex < 0) {
        this.log('请选择特征')
        return
      }
      const ch = this.characteristics[this.selectedCharIndex]
      if (!ch.properties.read) {
        this.log('该特征不可读')
        return
      }
      try {
        const res = await Bluetooth.readCharacteristic(this.connectedDeviceId, ch.serviceId || ch.serviceUuid || ch.service, ch.uuid || ch.characteristicUuid || ch.uuid)
        const hex = Bluetooth.arrayBufferToHex(res)
        const text = Bluetooth.arrayBufferToString(res)
        this.log('读取到 HEX: ' + hex)
        this.log('读取到 TEXT: ' + text)
      } catch (err) {
        this.log('读取失败: ' + JSON.stringify(err))
      }
    },

    async toggleNotify() {
      if (this.selectedCharIndex < 0) {
        this.log('请选择特征')
        return
      }
      const ch = this.characteristics[this.selectedCharIndex]
      if (!ch.properties.notify && !ch.properties.indicate) {
        this.log('该特征不支持通知/指示')
        return
      }
      try {
        if (!this.isNotifying) {
          await Bluetooth.notify(this.connectedDeviceId, ch.serviceId || ch.serviceUuid || ch.service, ch.uuid || ch.characteristicUuid || ch.uuid, true)
          this.isNotifying = true
          this.log('已开启通知')
        } else {
          await Bluetooth.notify(this.connectedDeviceId, ch.serviceId || ch.serviceUuid || ch.service, ch.uuid || ch.characteristicUuid || ch.uuid, false)
          this.isNotifying = false
          this.log('已关闭通知')
        }
      } catch (err) {
        this.log('通知设置失败: ' + JSON.stringify(err))
      }
    },

    onConnectionStateChange(res) {
      this.log('连接状态变化: ' + JSON.stringify(res))
      if (res.connected === false && res.deviceId === this.connectedDeviceId) {
        this.log('连接断开：' + res.deviceId)
        this.connectedDeviceId = null
        this.connectedDeviceName = ''
        this.characteristics = []
        this.services = []
      }
    },

    onCharacteristicChanged(data) {
      // data: { deviceId, value: ArrayBuffer, serviceId, characteristicId }
      const hex = Bluetooth.arrayBufferToHex(data.value)
      const txt = Bluetooth.arrayBufferToString(data.value)
      this.log(`通知来自 ${data.deviceId} HEX:${hex} TXT:${txt}`)
    },

    async disconnect() {
      if (!this.connectedDeviceId) return
      try {
        await Bluetooth.closeConnection(this.connectedDeviceId)
        this.log('断开连接成功')
        this.connectedDeviceId = null
        this.connectedDeviceName = ''
        this.characteristics = []
        this.services = []
      } catch (err) {
        this.log('断开失败: ' + JSON.stringify(err))
      }
    }
  },

  onUnload() {
    // 页面卸载时清理
    this.disconnect()
    Bluetooth.offDeviceFound(this.onDeviceFound)
  }
}
</script>

<style>
.page { padding: 12px; }
.section { margin-bottom: 12px; }
.device { display: flex; align-items: center; justify-content: space-between; margin: 6px 0; }
.row { display:flex; gap:8px; margin-top:8px; }
.log { margin-top:12px; max-height:200px; overflow:auto; background:#f7f7f7; padding:8px; }
.char { margin-top:8px; font-size:12px; color:#666; }
</style>
